﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TCPTest
{
    public class Board
    {
        public const int BOARD_SIZE = 15;
        public SpaceColor[][] board = new SpaceColor[BOARD_SIZE][];
        Stack<Move> moveStack = new Stack<Move>();

        public SpaceColor[][] getBoard()
        {
            return board;
        }

        public Board() 
        {
            moveStack.Clear();
            for (int i = 0; i < BOARD_SIZE; i++)
                board[i] = new SpaceColor[BOARD_SIZE];

            for (int i = 0; i < BOARD_SIZE; i++)
                for (int j = 0; j < BOARD_SIZE; j++)
                    board[i][j] = SpaceColor.EMPTY;
        }

        public override string ToString()
        {
            byte x, y;
            string result = "  1 2 3 4 5 6 7 8 9 a b c d e f";

            for (x = 0; x < BOARD_SIZE; x++)
            {
                result += "\r\n" + Move.toHexDigit(x) + " ";
                for (y = 0; y < BOARD_SIZE; y++)
                    result += spaceToString(board[x][y]) + " ";
            }

            result += "\r\n";

            return result;
        }

        private string spaceToString(SpaceColor space)
        {
            switch (space)
            {
                case SpaceColor.EMPTY: return "-";
                case SpaceColor.BLACK: return "@";
                case SpaceColor.WHITE: return "O";
            }
            return "";
        }

        public void doMove(Move move)
        {
            if (board[move.x][move.y] != SpaceColor.EMPTY)
                throw new Exception("Illegal move!");
            move.previousColor = board[move.x][move.y];
            board[move.x][move.y] = move.color;
            moveStack.Push(move);
        }
        public void undoMove()
        {
            Move move = moveStack.Pop();
            board[move.x][move.y] = move.previousColor;
        }

        public bool gameEnd(){
            if(terminatingCondition(SpaceColor.WHITE))
                return true;
            else if (terminatingCondition(SpaceColor.BLACK))
                return true;

            return false;
        }

        public bool terminatingCondition(SpaceColor color)
        {
            int count = 0;
            for (byte i = 0; i < 15; i++)
                for (byte j = 0; j < 15; j++)
                {
                    if (board[i][j] == color)
                        count++;
                    else
                        count = 0;

                    if (count >= 5)
                        return true;
                }

            count = 0;
            for (byte i = 0; i < 15; i++)
                for (byte j = 0; j < 15; j++)
                {
                    if (board[j][i] == color)
                        count++;
                    else
                        count = 0;

                    if (count >= 5)
                        return true;
                }

            //Down Diagonals
            for (byte i = 0; i < 11; i++)
                for (byte j = 0; j < (15 - i); j++) // Down diagonals along X axis
                {
                    if (board[i + j][j] == color)
                        count++;
                    else
                        count = 0;

                    if (count >= 5)
                        return true;
                }

            for (byte i = 0; i < 11; i++)
                for (byte j = 0; j < (15 - i); j++) // Down diagonals along Y axis
                {
                    if (board[j][i + j] == color)
                        count++;
                    else
                        count = 0;

                    if (count >= 5)
                        return true;
                }

            //Up Diagonals
            for (byte i = 3; i <= 14; i++)
                for (byte j = 0; j <= i; j++) // Up diagonals along X axis
                {
                    if (board[i - j][j] == color)
                        count++;
                    else
                        count = 0;

                    if (count >= 5)
                        return true;
                }
            for (byte i = 3; i <= 14; i++)
                for (byte j = 0; j <= i; j++) // Up diagonals along X axis
                {
                    if (board[j][i - j] == color)
                        count++;
                    else
                        count = 0;

                    if (count >= 5)
                        return true;
                }

            return false;
        }
   }
}
